package main

import (
	"log"

	"github.com/gotk3/gotk3/gtk"
)

func main() {
	gtk.Init(nil)

	win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
	if err != nil {
		log.Fatal("无法创建 window:", err)
	}
	win.SetTitle("网格示例")
	win.SetDefaultSize(500, 300)
	win.Connect("destroy", func() {
		gtk.MainQuit()
	})
	//创建一个新的网格小部件来排列子小部件
	grid, err := gtk.GridNew()
	if err != nil {
		log.Fatal("无法创建 grid:", err)
	}
	//gtk.Grid 嵌入了一个 Orientable 结构来模拟 GtkOrientable GInterface。将方向从默认水平设置为垂直。
	grid.SetOrientation(gtk.ORIENTATION_VERTICAL)
	//创建一些小部件以放入网格。
	lab, err := gtk.LabelNew("只是一个标签")
	if err != nil {
		log.Fatal("无法创建 label:", err)
	}

	btn, err := gtk.ButtonNewWithLabel("带标签的按钮")
	if err != nil {
		log.Fatal("无法创建 button:", err)
	}

	entry, err := gtk.EntryNew()
	if err != nil {
		log.Fatal("无法创建 entry:", err)
	}
	// 小数
	spnBtn, err := gtk.SpinButtonNewWithRange(0.0, 1.0, 0.001)
	if err != nil {
		log.Fatal("无法创建 spin button:", err)
	}

	nb, err := gtk.NotebookNew()
	if err != nil {
		log.Fatal("无法创建 notebook:", err)
	}
	//使用 gtk.Grid 调用 (gtk.Container).Add() 将按添加顺序将小部件彼此相邻添加，当网格处于水平方向时，添加到最后添加的小部件的右侧，并在如果网格处于垂直方向，则为最后添加的小部件的底部。以这种方式使用网格的工作方式类似于 gtk.Box，但与 gtk.Box 不同的是，gtk.Grid 将尊重其子部件的 expand 和 margin 属性。
	grid.Add(btn)
	grid.Add(lab)
	grid.Add(entry)
	grid.Add(spnBtn)
	//也可以通过调用 (gtk.Grid).Attach() 添加小部件以指定将小部件放置在网格中的位置，以及可选的跨越多少行和列。
	//// 当使用 (gtk.Container).Add() 添加新小部件时，根据需要自动将额外的行和列添加到网格中，或者，如本例所示，使用 (gtk.Grid).Attach()。
	//// 在这种情况下，在上面插入的小部件旁边添加了一个笔记本。笔记本小部件插入的左侧位置为 1，顶部位置为 1（从与按钮相同的垂直位置开始），宽度为 1 列，高度为 2 行（向下跨越到与按钮相同的垂直位置）入口）。
	//// 此示例还演示了并非网格的每个区域都必须包含小部件。特别是，标签右侧和旋转按钮右侧的区域不包含小部件。
	grid.Attach(nb, 1, 1, 1, 2)
	nb.SetHExpand(true)
	nb.SetVExpand(true)
	//向笔记本添加子小部件和选项卡标签，以便呈现。
	nbChild, err := gtk.LabelNew("笔记本内容")
	if err != nil {
		log.Fatal("无法创建 button:", err)
	}
	nbTab, err := gtk.LabelNew("标签")
	if err != nil {
		log.Fatal("无法创建 label:", err)
	}
	nb.AppendPage(nbChild, nbTab)

	//将网格添加到窗口，并显示所有小部件。
	win.Add(grid)
	win.ShowAll()

	gtk.Main()
}
